home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright Cornell University 1986. All rights are reserved.
-
- scrinit.c contains scr_init, which initializes the screen and
- create FONT bitmaps if needed (on the small-screen Mac),
- and a routine to save the screen location on exit.
-
- */
-
- #include <em.h>
-
- #include <h19.h>
- #include <config.h>
- #include <macdefs.h>
- #include <cntldefs.h>
- #include <resdefs.h>
-
- FONTS * fontarr[NOATTRS]; /* array of fonts for zapchar */
- char * fontskiparr[NOATTRS]; /* array of skip array ptrs for zapbuf */
-
- char * strfontbuild = "Using fast-drawing mode; building fonts...";
- char * strfonterr = "to build font"; /* memory out error tag */
-
- BitMap copybits;
-
- PicHandle iconpict; /* a little picture of 3270 screen for shrink control */
-
- extern savewindpos(); /* forward declaration */
-
- /* values saved in refCon for window automatic configuration ... */
- #define REFWINDOWSHOW 0x00000001
-
-
- /* Initialize the most basic fundaments */
-
- scrinit()
- {
- register int count; /* all purpose counter */
- WindowPtr tempwindow;
- Handle gdev; /* handle to graphics devices */
-
- paramptr = GetSysPPtr(); /* user set parameters for blinking */
-
- shrinkpict = GetResource('PICT', (short) 1);
- tapepict = GetResource('PICT', (short) 2);
-
- /* first set the direct to screen table fontskiparr to all
- skips and then correct so non-blank fonts use skiparr */
- for (count = 0; count < NOATTRS; count++)
- fontskiparr[count] = &allskiparr[0];
- fontskiparr[0] = &skiparr[0];
- fontskiparr[4] = &skiparr[0];
- fontskiparr[8] = &skiparr[0];
-
- /* set up the skip array; only the cases of zero and space are worthwhile */
- skiptest = &skiparr[0];
-
- skiparr[0] = TRUE;
- skiparr[32] = TRUE;
- skiparr[255] = TRUE;
-
- for (count = 0; count < NOCHARS; count++)
- /* allskiparr is a skiparr which is all true */
- allskiparr[count] = TRUE;
-
-
- iconpict = GetResource('PICT', (short) 0);
-
- exit_hook(savewindpos); /* add a hook to save the window's position on exit() */
-
- /* updateRgn is used in ScrollRect calls */
- updateRgn = NewRgn();
- emclip = NewRgn();
- q3clip = NewRgn();
-
- setdragrect();
-
- #ifdef USEHELPWINDOW
- buildhelpwindow();
- if (!(helpwindow = GetNewWindow((short) 2, (Ptr) NULL, (WindowPtr) NULL))) {
- error("Can't create help window");
- }
- #endif
- return(TRUE);
- }
-
-
- /* go through list of windows, reset resfile, then save */
-
- savewindpos()
- {
- struct winds ** conp = conns;
- struct winds * conend = &conp[conncount];
- register struct winds * twp;
-
- while (conp < conend) {
- twp = *conp++;
- if (twp == NULL)
- continue;
-
- if (twp->emwindow == (WindowPtr) NULL)
- continue;
-
- reopenconfig(twp);
- saveonewindpos(twp);
- closeconfig(twp);
- }
- FlushVol((StringPtr) NULL, (short) twp->resvol); /* flush the volume */
- }
-
-
- /* save the position of the emulator and icon windows into their WIND resources
- so they come up where they were left next time the user launches the program */
-
-
- saveonewindpos(conp)
- struct winds * conp;
- {
- Handle windh;
- Handle iconh;
- Handle texth;
- Handle sizeh; /* handle to font size resource */
- struct windres * windp; /* kluge for stupid compiler */
- struct windres * iconp;
- struct windres * textp;
- Point emwpos;
-
- struct windres {
- /* a WIND resource format (IM 1-302) */
-
- short top;
- short left;
- short bottom;
- short right;
- short procID;
- short visible;
- short goaway;
- long refCon;
- short title; /* actually a Str255 */
- };
-
- sizeh = Get1Resource('Fsiz', (short) 0);
- if (sizeh == NULL) {
- sizeh = NewHandle((long) 2);
- if (sizeh != (Handle) NULL) {
- AddResource(sizeh, 'Fsiz', (short) 0, "\P");
- if (ResError()) {
- DisposHandle(sizeh);
- sizeh = NULL;
- }
- }
- }
- if (sizeh != NULL) {
- *((short *) *sizeh) = conp->fontsize; /* save the font size */
- ChangedResource(sizeh);
- }
-
- windh = Get1Resource('WIND', (short) 0);
- if (windh == NULL) {
- windh = NewHandle((long) sizeof (struct windres));
- if (windh != (Handle) NULL) {
- windp = (struct windres *) *windh;
- memzero(windp, sizeof (struct windres));
-
- AddResource(windh, 'WIND', (short) 0, "\P");
- if (ResError()) {
- DisposHandle(windh);
- windh = NULL;
- }
- }
- }
- if (windh != NULL) {
- SetPort(conp->emwindow);
- windp = (struct windres *) *windh;
-
- emwpos.v = -29; /* -29 (offset) */
- emwpos.h = -10; /* -10 (offset) */
- LocalToGlobal(&emwpos);
-
- windp->procID = documentProc;
- windp->goaway = 0x0100;
- /* guarantee the window has a go-away box for backward compat */
-
- windp->top = emwpos.v;
- windp->left = emwpos.h;
- windp->bottom = windp->top
- + ((GrafPtr) conp->emwindow)->portRect.bottom
- - ((GrafPtr) conp->emwindow)->portRect.top;
- windp->right = windp->left
- + ((GrafPtr) conp->emwindow)->portRect.right
- - ((GrafPtr) conp->emwindow)->portRect.left;
-
- ChangedResource(windh);
- }
-
- iconh = Get1Resource('WIND', (short) 1);
- if (iconh == NULL) {
- iconh = NewHandle((long) sizeof (struct windres));
- if (iconh != (Handle) NULL) {
- iconp = (struct windres *) *iconh;
- memzero(iconp, sizeof (struct windres));
- iconp->procID = plainDBox;
-
- AddResource(iconh, 'WIND', (short) 1, "\P");
- if (ResError()) {
- DisposHandle(iconh);
- iconh = NULL;
- }
- }
- }
- if (iconh != NULL) {
- SetPort(conp->iconwindow);
- iconp = (struct windres *) *iconh;
-
- emwpos.v = 0;
- emwpos.h = 0;
- LocalToGlobal(&emwpos);
-
- iconp->top = emwpos.v;
- iconp->left = emwpos.h;
- iconp->bottom = iconp->top
- + ((GrafPtr) conp->iconwindow)->portRect.bottom
- - ((GrafPtr) conp->iconwindow)->portRect.top;
- iconp->right = iconp->left
- + ((GrafPtr) conp->iconwindow)->portRect.right
- - ((GrafPtr) conp->iconwindow)->portRect.left;
-
- ChangedResource(iconh);
- }
- #ifdef USETEXTWINDOWS
- /* save the text window position */
- texth = Get1Resource('WIND', (short) 2);
- if (texth == NULL) {
- texth = NewHandle((long) sizeof (struct windres));
- if (texth != (Handle) NULL) {
- textp = (struct windres *) *texth;
- memzero(textp, sizeof (struct windres));
-
- AddResource(texth, 'WIND', (short) 2, "\P");
- if (ResError()) {
- DisposHandle(texth);
- texth = NULL;
- }
- }
- }
- if (texth != NULL) {
- SetPort(conp->textwindow);
- textp = (struct windres *) *texth;
-
- emwpos.v = 0;
- emwpos.h = 0;
- LocalToGlobal(&emwpos);
-
- textp->procID = documentProc;
- textp->goaway = 0x0100;
- /* guarantee the window has a go-away box for backward compat */
-
- textp->top = emwpos.v;
- textp->left = emwpos.h;
- textp->bottom = textp->top
- + ((GrafPtr) conp->textwindow)->portRect.bottom
- - ((GrafPtr) conp->textwindow)->portRect.top;
- textp->right = textp->left
- + ((GrafPtr) conp->textwindow)->portRect.right
- - ((GrafPtr) conp->textwindow)->portRect.left;
-
- if (conp->hidetextwindow)
- /* don't show text window next startup if it's hidden */
- textp->refCon &= ~REFWINDOWSHOW;
- else
- textp->refCon |= REFWINDOWSHOW;
-
- ChangedResource(texth);
- }
- #endif
-
- UpdateResFile(conp->resfid);
- FlushVol((StringPtr) NULL, (short) conp->resvol); /* flush the volume */
-
- if (windh)
- ReleaseResource(windh);
- if (iconh)
- ReleaseResource(iconh);
- if (sizeh)
- ReleaseResource(sizeh);
-
- }
-
-
- /* set a shield rectangle in global coordinates for suppressing cursor */
-
- setshield(twp)
- struct winds * twp;
- {
- GrafPtr oport;
-
- GetPort(&oport);
- SetPort(twp->emwindow);
-
- /* make the cursor shield test area if we're using direct screen drawing */
- twp->zaprect.top = 0;
- twp->zaprect.left = 0;
- twp->zaprect.bottom = twp->emwindow->portRect.bottom;
- twp->zaprect.right = twp->emwindow->portRect.right;
- /* TODO should use bigrect? */
-
- LocalToGlobal((Point *) &twp->zaprect);
- LocalToGlobal((Point *) &twp->zaprect.bottom);
- /* put the shield rect into global coord for ShieldCursor */
-
- SetPort(oport);
- }
-
-
- /* build the array of addresses of line starts on the physical screen */
-
- setlinestarts(twp)
- struct winds * twp;
- {
- register unsigned long count;
- register unsigned long offset;
- register short * drawbase; /* offset from ScrnBase */
- unsigned long rowwords = twp->screenbytes / 2;
- Point point;
-
- /* get the offset from the top left corner of the screen we're on */
- point.h = -10;
- point.v = -29;
- LocalToGlobal(&point);
- point.h -= twp->gdRect.left;
- point.v -= twp->gdRect.top;
- /* gdRect has the global coordinates of the graphics device */
-
- drawbase = twp->screenbase + 1
- + (rowwords * SKIPLINES)
- + (twp->voffset * rowwords);
- /* the original origin for zap dsdrawing */
-
- offset = (((point.v - 20) * rowwords) + (point.h / 16));
- /* offset = number of words = rows below original zap pos * screenbytes
- + bytes offset from left origin at 0 */
- /* - 20 for offset from original screen vpos */
-
- drawbase += offset;
-
- if (twp->startarr != NULL)
- DisposPtr(twp->startarr);
- twp->startarr = NewPtr((Size) 4 * emdp->linecount);
- if (twp->startarr == NULL) {
- twp->dsdraw = FALSE;
- return(-1);
- }
-
- /* initialize the linestarts screenmap pointer array for zapchar */
- for (count = 0; count <= emdp->lastrow;
- count++, drawbase += (rowwords * twp->lineheight)) {
-
- *(twp->startarr + count) = drawbase;
- }
-
- return(0);
- }
-
-
-
- alignwind(twp, moveleft)
- struct winds * twp;
- int moveleft;
- {
- short fraction;
- Point point;
-
- point.h = -10;
- point.v = -29;
- LocalToGlobal(&point);
- fraction = (point.h % 16);
- if (fraction) {
- /* make sure the window is aligned properly */
- if (point.h < 0)
- fraction = -fraction;
- else
- fraction = 16 - fraction;
-
- if (moveleft)
- /* make it hop to the left rather than the right when
- user drags to the left */
- fraction -= 16;
-
- /* now get global coordinates */
- point.v = twp->emwindow->portRect.top;
- point.h = twp->emwindow->portRect.left;
- LocalToGlobal(&point);
-
- MoveWindow(twp->emwindow, (short) (point.h + fraction), point.v, (Boolean) FALSE);
- }
- }
-
- /* TODO use greyRgn? */
-
- setdragrect()
- {
- dragrect.top = 0;
- dragrect.left = 0;
- dragrect.bottom = 10000;
- dragrect.right = 10000;
- }
-
-
- testdsall()
- {
- /* go through window list and reset dsdraw correctly */
- GrafPtr oport;
- struct winds ** conp = conns;
- struct winds * conend = &conp[conncount];
- struct winds * twp;
- struct winds * oemdp = emdp;
-
- GetPort(&oport);
-
- /* go through window list and try out dsdraw */
- while (conp < conend) {
- twp = *conp++;
- if (twp == NULL || twp->emwindow == NULL)
- continue;
-
- testds(twp); /* leaves port set to emwindow */
- InvalRect(&twp->bigrect); /* guarantee it's redrawn */
- }
- SetPort(oport);
- }
-
-
- /* Can we use the direct to screen drawing routines?
- If so, set them up.
- */
-
- testds(twp)
- struct winds * twp;
- {
- Rect wrect;
- Rect intersect;
- GDHandle gdev;
-
- SetPort(twp->emwindow);
- colorupd(twp); /* update colormap */
- if (!trydsdraw
- || ! (twp->fontwidth == 6
- || (twp->fontwidth == 8 && twp->fontheight == 19) )
- || ! (twp->linecount == 24 && twp->linelength == 80)
- ) {
- /* font is not the two sizes currently available,
- or the screen is a non-standard size...
- TODO could other 8 bit wide sizes be supported?
- to live dangerously:
- || twp->linecount > 32
- || twp->linelength != 80
- */
- useqd(twp);
- return(FALSE);
- }
- wrect = twp->bigrect;
- LocalToGlobal(&wrect.top);
- LocalToGlobal(&wrect.bottom);
- /* twp->emwindow->portRect was used before the ACTUAL ds area, bigrect,
- replaced it.
- wrect is a bit safer but bigrect allows ds drawing on 640 bit wide
- screens... */
-
- if (environs.hasColorQD) {
- for (gdev = GetDeviceList(); gdev != NULL; gdev = (*gdev)->gdNextGD) {
- if ( ! TestDeviceAttribute(gdev, screenDevice)
- || ! TestDeviceAttribute(gdev, screenActive) )
- /* ignore devices which are not active screens */
- continue;
- if (SectRect(&wrect, &(*gdev)->gdRect, &intersect)) {
- /* get the intersection of the rectangles */
- if (EqualRect(&wrect, &intersect)) {
- /* the intersection == wrect, window is completely in gdevice */
- if ((*(*gdev)->gdPMap)->pixelSize == 1) {
- /* we're on a mono screen */
- /* save globals if this window is the current output window */
- unsigned long basetemp;
-
- if (twp == emdp) {
- savecontext(emdp);
- }
-
- twp->gdRect = (*gdev)->gdRect;
- twp->screenbase = (*(*gdev)->gdPMap)->baseAddr;
-
- /* fix mis-advertised NuBus addresses */
- basetemp = twp->screenbase;
- if (basetemp & 0xF0000000) {
- /* the address is on the NuBus */
- if (! (basetemp & 0x00F00000) ) {
- unsigned long theslot;
-
- /* this NuBus address won't work in 24-bit mode,
- we must add the slot# for some Apple boards!
- Designing Cards & Drivers 2nd Ed. p. 90
-
- $Fs0x xxxx what some Apple boards give
- (e.g., 2-page display)
- $Fssx xxxx 24 & 32-bit format compatible
- after StripAddress(), since
- 900000 -> F9000000 automatically
- */
-
- theslot = (basetemp & 0x0F000000) >> 4;
- basetemp |= theslot;
- twp->screenbase = basetemp;
- }
- }
- /* StripAddress(twp->screenbase); */
- twp->screenbytes = (*(*gdev)->gdPMap)->rowBytes & 0x0FFF;
- /* hey, sometimes we get a negative value. ?!???!
- Also, fails to work with E-Machines monitor
- 4096 * 8 = 32000 ought to be large enough... */
- twp->screenrem = twp->screenbytes - 64; /* corrects clrit */
- useds(twp);
-
- /* update globals if this window is the current output window */
- if (twp == emdp) {
- setcontext(emdp);
- }
- return(TRUE);
- }
- /* the window overlaps; on 512 & 640 screens, try to force? */
- }
- break; /* give up */
- }
- }
- /* hey, we're not anywhere on the screen! */
- useqd(twp);
- return(FALSE);
- }
- else if (screenBits.bounds.right == 512 && twp->fontwidth == 6) {
- /* window is OK if 9 pt. font */
- if (twp == emdp) {
- savecontext(emdp);
- }
- olddsbase(twp);
- useds(twp);
-
- /* update globals if this window is the current output window */
- if (twp == emdp) {
- setcontext(emdp);
- }
- return(TRUE);
- }
- else if (SectRect(&wrect, &screenBits.bounds, &intersect)) {
- if (EqualRect(&wrect, &intersect)) {
- /* window is completely in gdevice */
- if (twp == emdp) {
- savecontext(emdp);
- }
-
- olddsbase(twp);
- useds(twp);
-
- /* update globals if this window is the current output window */
- if (twp == emdp) {
- setcontext(emdp);
- }
- return(TRUE);
- }
- }
- useqd(twp);
- return(FALSE);
- }
-
-
- /* get the offset from the origin of the current window's graphics device */
-
- LocalToLocalMap(twp, point)
- struct winds * twp;
- Point * point;
- {
- if (environs.hasColorQD) {
- /* color QD replaces portbits with a PixMap Handle ... */
- point->v = ((GrafPtr) twp->emwindow)->portRect.top
- - (* (PixMapHandle) (((GrafPtr) twp->emwindow)->portBits.baseAddr))->bounds.top;
- point->h = ((GrafPtr) twp->emwindow)->portRect.left
- - (* (PixMapHandle) (((GrafPtr) twp->emwindow)->portBits.baseAddr))->bounds.left;
- }
- else {
- point->v = ((GrafPtr) twp->emwindow)->portRect.top
- - ((GrafPtr) twp->emwindow)->portBits.bounds.top;
- point->h = ((GrafPtr) twp->emwindow)->portRect.left
- - ((GrafPtr) twp->emwindow)->portBits.bounds.left;
- }
- }
-
-
- /* is the top left corner of the window in the display? */
-
- indisplay(thewind)
- WindowPtr thewind;
- {
- Point emwtop;
- GrafPtr oport;
- int retval = FALSE;
-
- GetPort(&oport);
- SetPort(thewind);
-
- if (((WindowPeek) thewind)->windowKind == EMWINDKIND) {
- emwtop.v = -39;
- emwtop.h = 20;
- }
- else {
- emwtop.v = 5;
- emwtop.h = 10;
- }
-
- LocalToGlobal(&emwtop);
-
- if (PtInRgn(pass(emwtop), GetGrayRgn()))
- retval = TRUE;
- else
- retval = FALSE;
-
- SetPort(oport);
- return(retval);
- }
-
-
- /* build the character tables TODO font size change triggers font rebuild
- return -1 if can't build font */
-
- buildfonts(twp)
- struct winds * twp;
- {
- WindowPtr tempwindow;
- GrafPtr oldport;
- int count;
- Rect windRect;
-
- if (twp->fontwidth == 6 && font.font1 != NULL)
- /* already made */
- return(0);
-
- if (twp->fontwidth == 8 && font.font3 != NULL)
- /* already made */
- return(0);
-
- windRect.top = 20;
- windRect.left = 0;
- windRect.bottom = 342;
- windRect.right = 512;
-
- if (TRUE) {
- /* was if (dsdraw) -- make all the special direct-to-screen fonts */
-
- GetPort(&oldport);
- if (!(tempwindow = NewWindow((Ptr) NULL, &windRect, "\P",
- (Boolean) FALSE, (short) 0, (WindowPtr) NULL, (Boolean) 0, 0L))) {
- SetPort(oldport);
- return(-1);
- }
- SetPort(tempwindow);
-
- if (twp->fontwidth == 6) {
- /* build the 9 pt fonts */
-
- #ifndef MERGEDVTCHARS
- if (!memtest((long) 6 * 2 * (2 * NOCHARS * 12), strfonterr)) {
- /* not enough memory for operation, which is 72K */
- return(-1);
- }
- #else
- if (!memtest((long) 4 * 2 * (2 * NOCHARS * 12), strfonterr)) {
- /* not enough memory for operation, which is 72K */
- return(-1);
- }
- #endif
- fixgrafport(6, 12);
-
- prerr25(strfontbuild);
- if (
- buildfont(&font, twp->normfont, 9, 9, 12, 6, FALSE)
- || buildfont(&invfont, twp->normfont, 9, 9, 12, 6, TRUE)
- || buildfont(&boldfont, twp->highfont, 9, 9, 12, 6, FALSE)
- || buildfont(&invboldfont, twp->highfont, 9, 9, 12, 6, TRUE)
- #ifndef MERGEDVTCHARS
- || buildfont(&bvtfont, twp->vtfont, 9, 9, 12, 6, FALSE)
- || buildfont(&invbvtfont, twp->vtfont, 9, 9, 12, 6, TRUE)
- #endif
-
- ) {
- freefont(6);
- return(-1);
- }
-
- chofftab9 = NewPtr((Size) (2 * NOCHARS));
- if (chofftab9 == NULL) {
- freefont(6);
- return(-1);
- }
-
- for (count = 0; count < NOCHARS; count++) {
- *(chofftab9 + count) = count * 2 * 12;
- }
- }
- else if (twp->fontwidth == 8) {
- /* build the 19 pt font, used to do 14 pt */
- #ifndef MERGEDVTCHARS
- if (!memtest((long) 6 * (2 * NOCHARS * 19), strfonterr)) {
- /* not enough memory for operation, which is 45K */
- return(-1);
- }
- #else
- if (!memtest((long) 4 * (2 * NOCHARS * 19), strfonterr)) {
- /* not enough memory for operation, which is 45K */
- return(-1);
- }
- #endif
-
- fixgrafport(8, 19);
-
- prerr25(strfontbuild);
- /* was 14, 12, 14, for 14 point font */
- if (
- buildfont(&font, twp->normfont, 16, 14, 19, 8, FALSE)
- || buildfont(&invfont, twp->normfont, 16, 14, 19, 8, TRUE)
- || buildfont(&boldfont, twp->highfont, 16, 14, 19, 8, FALSE)
- || buildfont(&invboldfont, twp->highfont, 16, 14, 19, 8, TRUE)
- #ifndef MERGEDVTCHARS
- || buildfont(&bvtfont, twp->vtfont, 16, 14, 19, 8, FALSE)
- || buildfont(&invbvtfont, twp->vtfont, 16, 14, 19, 8, TRUE)
- #endif
- ) {
- freefont(8);
- return(-1);
- }
-
- chofftab12 = NewPtr((Size) (2 * NOCHARS));
- if (chofftab12 == NULL){
- freefont(8);
- return(-1);
- }
-
- for (count = 0; count < NOCHARS; count++) {
- *(chofftab12 + count) = count * 2 * 19;
- }
- }
- else
- return(-1);
-
- thefont = &font;
-
- /* load the font array for zapline; only 0, 4, & 8 are really defined */
- fontarr[0] = &font;
- fontarr[4] = &font;
- fontarr[8] = &boldfont;
-
- DisposeWindow(tempwindow);
- DisposPtr(copybits.baseAddr);
-
- SetPort(oldport);
- }
- return(0);
- }
-
-
-
- buildfont(fontp, fontid, fontsize, fontascent, fontheight, fontwidth, invert)
- FONTS * fontp;
- short fontid;
- int fontsize;
- int fontascent;
- int fontheight;
- int fontwidth;
- int invert;
- {
- register unsigned short *iptr; /* -> bitmap char image from DrawChar */
- register unsigned short *iptr1; /* -> FONT1 char images */
- register unsigned short *iptr2; /* -> FONT2 char images */
- short thechar;
- int count;
- Rect invrect;
-
- /* Make the inverted normal font */
- if (fontwidth == 6) {
- if (fontp->font1) {
- /* free the existing version */
- DisposPtr(fontp->font1);
- DisposPtr(fontp->font2);
- }
- iptr1 = fontp->font1 = (unsigned short *) NewPtr((Size) (2 * NOCHARS * fontheight));
- iptr2 = fontp->font2 = (unsigned short *) NewPtr((Size) (2 * NOCHARS * fontheight));
- if (iptr1 == NULL || iptr2 == NULL) {
- return(-1);
- }
- }
- else if (fontwidth == 8) {
- if (fontp->font3) {
- /* free the existing version */
- DisposPtr(fontp->font3);
- }
- iptr1 = fontp->font3 = (unsigned short *) NewPtr((Size) (2 * NOCHARS * fontheight));
- if (iptr1 == NULL) {
- return(-1);
- }
- }
-
-
- TextFont(fontid);
- TextSize((short) fontsize);
-
- invrect.top = 0;
- invrect.left = 0;
- invrect.bottom = fontheight;
- invrect.right = fontwidth;
-
- EraseRect(&thePort->portBits.bounds);
- if (fontwidth == 6) {
- for (thechar = 0; thechar < NOCHARS; thechar++) {
- /* clear the bitmap and draw the next character */
- MoveTo((short) 0, (short) fontascent);
- EraseRect(&invrect);
- DrawChar((char) thechar);
- if (invert)
- InvertRect(&invrect);
-
- iptr = thePort->portBits.baseAddr;
- for (count = 0; count < fontheight; count++) {
- *iptr2++ = *iptr;
- *iptr1++ = *iptr++ >> 2;
- }
- }
- }
- else if (fontwidth == 8) {
- for (thechar = 0; thechar < NOCHARS; thechar++) {
- /* clear the bitmap and draw the next character */
- MoveTo((short) 0, (short) fontascent);
- EraseRect(&invrect);
- DrawChar((char) thechar);
- if (invert)
- InvertRect(&invrect);
-
- iptr = thePort->portBits.baseAddr;
- for (count = 0; count < fontheight; count++) {
- *iptr1++ = *iptr++;
- }
- }
- }
- return(0);
- }
-
-
- /* free the storage associated with a (half-built) font */
-
- freefont(fontwidth)
- short fontwidth;
- {
- if (fontwidth == 6) {
- if (font.font1) DisposPtr(font.font1);
- if (font.font2) DisposPtr(font.font2);
- if (invfont.font1) DisposPtr(invfont.font1);
- if (invfont.font2) DisposPtr(invfont.font2);
- if (boldfont.font1) DisposPtr(boldfont.font1);
- if (boldfont.font2) DisposPtr(boldfont.font2);
- if (invboldfont.font1) DisposPtr(invboldfont.font1);
- if (invboldfont.font2) DisposPtr(invboldfont.font2);
- if (bvtfont.font1) DisposPtr(bvtfont.font1);
- if (bvtfont.font2) DisposPtr(bvtfont.font2);
- if (invbvtfont.font1) DisposPtr(invbvtfont.font1);
- if (invbvtfont.font2) DisposPtr(invbvtfont.font2);
-
- font.font1 = NULL;
- font.font2 = NULL;
- invfont.font1 = NULL;
- invfont.font2 = NULL;
- boldfont.font1 = NULL;
- boldfont.font2 = NULL;
- invboldfont.font1 = NULL;
- invboldfont.font2 = NULL;
- bvtfont.font1 = NULL;
- bvtfont.font2 = NULL;
- invbvtfont.font1 = NULL;
- invbvtfont.font2 = NULL;
- }
- if (fontwidth == 8) {
- if (font.font3) DisposPtr(font.font3);
- if (invfont.font3) DisposPtr(invfont.font3);
- if (boldfont.font3) DisposPtr(boldfont.font3);
- if (invboldfont.font3) DisposPtr(invboldfont.font3);
- if (bvtfont.font3) DisposPtr(bvtfont.font3);
- if (invbvtfont.font3) DisposPtr(invbvtfont.font3);
-
- font.font3 = NULL;
- invfont.font3 = NULL;
- boldfont.font3 = NULL;
- invboldfont.font3 = NULL;
- bvtfont.font3 = NULL;
- invbvtfont.font3 = NULL;
- }
- error("Not enough memory to build direct-to-screen font");
- }
-
-
- /* move the controls on the right hand side of the window out from their
- default size */
-
- screxpand()
- {
- int dv;
- int dh;
- int emv; /* emulator height */
- int emh; /* emulator width */
-
- /*
- 480, 288 original 9 pt dimensions
- + 29, + 30 for controls & stuff
- */
-
- emh = (emdp->lastcol + 1) * emdp->fontwidth + 2 * emdp->hoffset;
- dh = emh - 480;
-
- emv = (emdp->lastrow + 1) * emdp->lineheight + emdp->voffset;
- dv = emv - 288;
-
- prettyresize(dh, dv);
- SizeWindow(emwindow, (short) 509 + dh, (short) 318 + dv, (Boolean) FALSE);
-
- #ifndef SIZETEXTWINDOW
- textwsize(emh + 28, emv);
- #endif
- }
-
-
-
- /* create a new window & accompanying iconwindow
- sets globals
- */
-
- char * makewinderr = "Not enough memory to make a window";
-
- makewind()
- {
- WindowPtr emw; /* -> emulator windowptr */
- WindowPtr iconw; /* -> icon windowptr */
- WindowPtr textw; /* -> icon windowptr */
- GrafPtr oldport;
-
- if (!memtest((long) (3 * sizeof(WindowRecord) +
- (2 * emdp->linelength * emdp->linecount) ), "to make window")) {
- return(-1);
- }
- GetPort(&oldport);
- if ((emdp->sel_tm = tm_alloc()) == NULL) {
- error(makewinderr);
- return(-1);
- }
- if ((emdp->timer25 = tm_alloc()) == NULL) {
- error(makewinderr);
- return(-1);
- }
- #ifdef USETEXTWINDOWS
- if (!(textw = GetNewWindow((short) 2, (Ptr) NULL, (WindowPtr) -1L))) {
- SetPort(oldport);
- error(makewinderr);
- return(-1);
- }
- #endif
- if (environs.hasColorQD) {
- if (!(iconw = GetNewCWindow((short) 1, (Ptr) NULL, (WindowPtr) NULL))) {
- SetPort(oldport);
- error(makewinderr);
- return(-1);
- }
- if (!(emw = GetNewCWindow((short) 0, (Ptr) NULL, (WindowPtr) -1L))) {
- DisposeWindow(iconw);
- SetPort(oldport);
- error(makewinderr);
- return(-1);
- }
- }
- else {
- if (!(iconw = GetNewWindow((short) 1, (Ptr) NULL, (WindowPtr) NULL))) {
- SetPort(oldport);
- error(makewinderr);
- return(-1);
- }
- if (!(emw = GetNewWindow((short) 0, (Ptr) NULL, (WindowPtr) -1L))) {
- DisposeWindow(iconw);
- SetPort(oldport);
- error(makewinderr);
- return(-1);
- }
- emdp->color = FALSE;
- }
-
- emdp->emwindow = emw;
- emdp->iconwindow = iconw;
-
- emwindow = emw; /* set globals */
- iconwindow = iconw;
-
- ((WindowPeek) emw)->refCon = emdp;
- ((WindowPeek) iconw)->refCon = emdp;
- /* refcon points back to our connection structure */
-
- ((WindowPeek) emw)->windowKind = EMWINDKIND;
- ((WindowPeek) iconw)->windowKind = ICONWINDKIND;
-
- #ifdef USETEXTWINDOWS
- emdp->textwindow = textw;
- if (((WindowPeek) textw)->refCon & REFWINDOWSHOW)
- /* hide the text window unless it's been brought up before... */
- emdp->hidetextwindow = FALSE;
- else
- emdp->hidetextwindow = TRUE;
-
- ((WindowPeek) textw)->refCon = emdp;
- ((WindowPeek) textw)->windowKind = TEXTWINDKIND;
- #endif
-
- SetPort(iconw);
- TextSize(9);
- /* position the iconwindow... this is a bit bogus since it will always haul
- the icons onto the Main Screen (with the menus) or is it bogus? */
-
- if ( !indisplay(iconwindow)) {
- /* move the iconwindow to the bottom right if it hasn't been moved before
- or is out of sight */
- MoveWindow(iconwindow, (short) (screenBits.bounds.right - 60),
- (short) (screenBits.bounds.bottom - 140 + conncount * 10), (Boolean) 0);
- }
-
-
- SetPort(emw);
-
- initwind();
-
- /* adjust margins */
- SetOrigin((short) -10, (short) -29);
- /* for zapchar,
- h = 1 word - 6 bits over,
- v = SKIPLINES - windRect.top */
-
- TextFont(emdp->highfont); /* make bold font the default */
- TextSize((short) 9);
- TextMode(srcCopy); /* copy mode will obliterate w/o erase */
-
- builddiacritics(); /* only needed once, but must be done in
- window context or Finder gets screwed up! */
-
- /* move & resize the window if necessary */
-
- SizeWindow(emw, (short) 509, (short) 318, (Boolean) FALSE);
- #ifdef USETEXTWINDOWS
- #ifndef SIZETEXTWINDOW
- SizeWindow(textw, (short) 509, (short) 298, (Boolean) FALSE);
- /* make all windows start out small... */
- #endif
- #endif
-
- prettyinit();
-
- setfontsize(emdp->fontsize);
-
- #ifdef USETEXTWINDOWS
- textwinit();
- #else
- emdp->textwindow = -1; /* make sure it can never be == FrontWindow */
- #endif
-
- screxpand();
- alignwind(emdp, FALSE);
-
- if (windtightfit(emdp) || !indisplay(emwindow) ) {
- /* if the window is not in the display, move if it necessary */
- fitwindow(emdp);
- }
-
-
- ClipRect(&((GrafPtr) emw)->portRect); /* make the clip rect smaller so small macs do diffrgn ok */
-
- controlinit(emw, emdp->ibm_keymode ? IBMRES : ASCRES); /* TODO delete? */
-
- pr25(0, nosessionstr); /* no session exists */
- ShowWindow(emw);
-
- #ifdef USETEXTWINDOWS
- if (!emdp->hidetextwindow)
- ShowWindow(textw); /* leave hidden if not saved as visible! */
- #endif
-
- setcontext(emdp); /* update globals before testds does savecontext() */
-
- testds(emdp);
- if (emdp->hhostname) {
- HLock(emdp->hhostname);
- windowtitle(emdp, *emdp->hhostname);
- HUnlock(emdp->hhostname);
- }
-
- }
-
-
- /* free the window and storage associated with it */
-
- killwind(twp)
- struct winds * twp;
- {
-
- if (twp->startarr != NULL)
- DisposPtr(twp->startarr);
-
- tm_clear(twp->sel_tm);
- tm_free(twp->sel_tm);
-
- tm_clear(twp->timer25);
- tm_free(twp->timer25);
-
- killcontrols(twp->emwindow);
- DisposeWindow(twp->emwindow);
- DisposeWindow(twp->iconwindow);
-
- #ifdef USETEXTWINDOWS
- /* release text window */
- TEDispose(twp->texthand);
- KillControls(twp->textwindow);
- DisposeWindow(twp->textwindow);
- twp->textwindow = NULL;
- #endif
- killwindmenu(twp->emwindow);
-
- if (twp->emwindow == keydp->emwindow) {
- keydp->emwindow = NULL;
- keywindow = NULL;
- }
-
- twp->emwindow = NULL;
- twp->iconwindow = NULL;
-
- InitCursor(); /* guarantee that the cursor is a visible arrow */
- }
-
-
-
- initwind()
- {
- /* set the size of the bigrect erase rectangle */
- emdp->bottommarg = BOTTOMMARG; /* bottom margin of emulator area */
- emdp->rightmarg = RIGHTMARG; /* right margin of emulator area */
- emdp->mrecttop = MRECTTOP; /* offset to top of mouse tracking rectangle */
- emdp->mrectbot = MRECTBOT; /* offset to bottom of mouse tracking */
-
- emdp->bigrect.top = TOPMARG;
- emdp->bigrect.left = LEFTMARG;
- emdp->bigrect.bottom = BOTTOMMARG;
- emdp->bigrect.right = RIGHTMARG;
-
- emdp->thefont = &font; /* default font */
-
- emdp->curstop = CURSTOP; /* top of the cursor */
-
- /* use vt100 by default */
-
- emdp->em = vt100;
- emdp->emstr = vt100str;
-
- vt100reset();
-
- return(0); /* all is cool */
- }
-
- /* free the ASCII emulator memory */
-
- ascii_free(twp)
- struct winds * twp;
- {
- if (twp->charr)
- DisposPtr(twp->charr);
- if (twp->tabset)
- DisposPtr(twp->tabset);
- }
-
- /* OK to use screenbits */
-
- olddsbase(twp)
- struct winds * twp;
- {
- twp->screenbase = (short *) *ScrnBase;
- twp->screenbytes = screenBits.rowBytes & 0x7FFF;
- twp->screenrem = screenbytes - 64; /* corrects clrit */
- }
-
-
-
- /* center the window in the middle of the screen
- window is hidden so we show it
-
- */
-
- centerwind(windp)
- WindowPtr windp;
- {
- Point pos;
- Point emwpos;
- GrafPtr topemwind;
-
- SetPort(windp);
- pos.v = 0;
- pos.h = 0;
-
- if (keywindow == NULL) {
- ShowWindow(windp);
- return;
- }
-
- LocalToGlobal(&pos);
-
- /* get original emwindow global coordinates */
- topemwind = keydp->emwindow;
- SetPort(topemwind);
- emwpos.v = -49; /* -29 (offset) - 20 (original global window top) */
- emwpos.h = -10; /* -10 (offset) */
-
- /* re-center the window over the main screen */
- emwpos.v = (screenBits.bounds.bottom - screenBits.bounds.top - 342) / 3;
- emwpos.h = (screenBits.bounds.right - screenBits.bounds.left - 512) / 2;
-
- MoveWindow(windp, pos.h + emwpos.h, pos.v + emwpos.v, (Boolean) 0);
-
- ShowWindow(windp);
- SetPort(windp);
- }
-
-
- /* center the window over the current emwindow; windows are already placed
- so they look good over standard window, so just shift 'em
- window is hidden so we show it
-
- */
-
- overwind(windp)
- WindowPtr windp;
- {
- Point pos;
- Point emwpos;
- GrafPtr topemwind;
-
- SetPort(windp);
- pos.v = 0;
- pos.h = 0;
-
- if (keywindow == NULL) {
- ShowWindow(windp);
- return;
- }
-
- LocalToGlobal(&pos);
-
- /* get original emwindow global coordinates */
- topemwind = keydp->emwindow;
- SetPort(topemwind);
- emwpos.v = -49; /* -29 (offset) - 20 (original global window top) */
- emwpos.h = -10; /* -10 (offset) */
-
- /* re-center the window (dialog, what have you) over the top window */
- emwpos.v += (topemwind->portRect.bottom - topemwind->portRect.top - 318) / 2;
- emwpos.h += (topemwind->portRect.right - topemwind->portRect.left - 509) / 2;
-
- LocalToGlobal(&emwpos);
-
- MoveWindow(windp, pos.h + emwpos.h, pos.v + emwpos.v, (Boolean) 0);
-
- ShowWindow(windp);
- SetPort(windp);
- }
-
-
- /* move the point from fixed global pos to one over the current topemwind */
-
- centerpoint(thept)
- Point * thept;
- {
- GrafPtr oport;
- Point emwpos;
- GrafPtr topemwind;
-
- if (keywindow == NULL)
- return;
-
- GetPort(&oport);
-
- /* get original emwindow global coordinates */
- topemwind = keydp->emwindow;
- SetPort(topemwind);
- emwpos.v = -49; /* -29 (offset) - 20 (original global window top) */
- emwpos.h = -10; /* -10 (offset) */
-
- #ifdef CENTEROVER
- /* re-center it over the top window */
- emwpos.v += (topemwind->portRect.bottom - topemwind->portRect.top - 318) / 2;
- emwpos.h += (topemwind->portRect.right - topemwind->portRect.left - 509) / 2;
-
- LocalToGlobal(&emwpos);
-
- #else
- /* the more standard way of doing it... */
- /* re-center the window over the main screen */
-
- emwpos.v = (screenBits.bounds.bottom - screenBits.bounds.top - 342) / 3;
- emwpos.h = (screenBits.bounds.right - screenBits.bounds.left - 512) / 2;
-
- #endif
-
- thept->v += emwpos.v;
- thept->h += emwpos.h;
-
- SetPort(oport);
- }
-
-
- /* dialog for user to OK saving a resource which has been modified */
-
- doconfig()
- {
- return(TRUE);
- }
-
-
-
- fixgrafport(width, height)
- short width;
- short height;
- {
- /* set up the BitMap used in copying the fonts to our buffers */
- Rect cliprect;
-
- copybits.baseAddr = (QDPtr) NewPtr((Size) 2 * 48);
- copybits.rowBytes = 2;
- copybits.bounds.top = 0;
- copybits.bounds.left = 0;
- copybits.bounds.bottom = height;
- copybits.bounds.right = 16;
-
- if (copybits.baseAddr == NULL)
- return(-1);
-
- SetPortBits(©bits);
-
- /* correct visRgn and clipRgn to allow drawing */
- RectRgn(thePort->visRgn, ©bits.bounds);
- cliprect.top = 0;
- cliprect.left = 0;
- cliprect.bottom = copybits.bounds.bottom;
- cliprect.right = copybits.bounds.right;
- ClipRect(&cliprect);
-
- /* set port size so right margin is big enough */
- PortSize(copybits.bounds.right, copybits.bounds.bottom);
-
- }
-
-
- /* put the window in an appropriate place if it somehow got somewhere
- inappropriate */
-
- fitwindow(twp)
- struct winds * twp;
- {
- if (twp->gdRect.right == 512) {
- if (twp->gdRect.bottom > 348) {
- /* same width but larger than original screen */
- MoveWindow(twp->emwindow, (short) 0, (short) 36, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
- #endif
- }
- else {
- /* make sure window OK on small mac screen */
- MoveWindow(twp->emwindow, (short) 0, (short) 20, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) 0, (short) 43, (Boolean) 0);
- #endif
- }
- }
- else if (twp->gdRect.right == 640) {
- /* 13" color monitor and Portrait Display */
- if (emdp->fontsize == 14) {
- /* make sure window fits and runs DS on a 640 wide screen */
- MoveWindow(twp->emwindow, (short) -16, (short) 36, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
- #endif
- }
- else if (emdp->fontsize == 16) {
- if (twp->gdRect.bottom <= 525) {
- /* make sure window fits and runs DS on a 640 wide X 512 V screen */
- MoveWindow(twp->emwindow, (short) -16, (short) -9, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) -6, (short) 14, (Boolean) 0);
- #endif
- }
- else {
- /* make sure window fits and runs DS on a 640 wide screen */
- MoveWindow(twp->emwindow, (short) -16, (short) 36, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) -6, (short) 55, (Boolean) 0);
- #endif
- }
- }
- else {
- MoveWindow(twp->emwindow, (short) 0, (short) 36, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
- #endif
- }
- }
- else {
- MoveWindow(twp->emwindow, (short) 0, (short) 36, (Boolean) 0);
- #ifdef USETEXTWINDOWS
- MoveWindow(twp->textwindow, (short) 0, (short) 55, (Boolean) 0);
- #endif
- }
- }
-
-
-
- setgdrect(twp)
- struct winds * twp;
- {
- Rect wrect;
- Rect intersect;
- GDHandle gdev;
- Point emwtop;
-
- SetPort(twp->emwindow);
- wrect = twp->bigrect;
- LocalToGlobal(&wrect.top);
- LocalToGlobal(&wrect.bottom);
-
- if (environs.hasColorQD) {
- /* make the screen which contains the upper left corner the home screen */
- emwtop.v = -39;
- emwtop.h = 20;
- LocalToGlobal(&emwtop);
- for (gdev = GetDeviceList(); gdev != NULL; gdev = (*gdev)->gdNextGD) {
- if ( ! TestDeviceAttribute(gdev, screenDevice)
- || ! TestDeviceAttribute(gdev, screenActive) )
- /* ignore devices which are not active screens */
- continue;
- if (PtInRect(pass(emwtop), &(*gdev)->gdRect)) {
- /* the first device with an intersection is the winner */
- twp->gdRect = (*gdev)->gdRect;
- return;
- }
- }
- /* if we reach here the point was off the screen, so we will look for
- any intersection... */
- for (gdev = GetDeviceList(); gdev != NULL; gdev = (*gdev)->gdNextGD) {
- if ( ! TestDeviceAttribute(gdev, screenDevice)
- || ! TestDeviceAttribute(gdev, screenActive) )
- /* ignore devices which are not active screens */
- continue;
- if (SectRect(&wrect, &(*gdev)->gdRect, &intersect)) {
- /* the first device with an intersection is the winner */
- twp->gdRect = (*gdev)->gdRect;
- return;
- }
- }
- /* if we reach here, the window is completely off the screen */
- }
- /* screenBits is our default */
- twp->gdRect = screenBits.bounds;
- }
-
-
- /* test to see whether the window may need to be coerced to fit */
-
- windtightfit(twp)
- struct winds * twp;
- {
- setgdrect(twp);
- if (twp->gdRect.right == 512)
- return(TRUE);
- else if (twp->gdRect.right == 640) {
- if (twp->fontsize == 16)
- return(TRUE);
- }
- return(FALSE);
- }
-
- /* set the emdp context window titles */
-
- windowtitle(twp, passtr)
- struct winds * twp;
- Str255 * passtr;
- {
- char macfile[256];
- FILE *textfp;
- int readcount;
- char filebuffer[514];
-
- SetWTitle(twp->emwindow, passtr);
- #ifdef USETEXTWINDOWS
- /* give the text window the same name with ".text" appended */
- ptoc(passtr);
- sprintf(&macfile[0], "%s.edit", passtr);
- ctop(passtr);
-
- ctop(&macfile[0]);
- SetWTitle(twp->textwindow, &macfile[0]);
- #define LOADTEXTWINDOWS
- #ifdef LOADTEXTWINDOWS
- /* automagically load up the text window with the text */
- tesetsel( (long) 0, (long) (*twp->texthand)->teLength, twp->texthand);
- TEDelete(twp->texthand);
- textctlupd(twp);
- SelView(twp);
-
- textfp = fopen(&macfile[0], "r");
- if (textfp != NULL) {
- while (TRUE) {
- readcount = fread(&filebuffer[0], 1, 512, textfp);
- if (readcount == 0) {
- /* we've read the whole file */
- break;
- }
- textwappend(&filebuffer[0], (long) readcount);
- }
- fclose(textfp);
- }
- #endif
- #endif
- }
-
-
-
- /* build a map of diacritical marks to handle spacing */
-
- builddiacritics()
- {
- register int count; /* all purpose counter */
-
- for (count = 0; count < NOCHARS; count++)
- if (CharWidth(count) == 0)
- isdiacritic[count] = 1;
- }
-
-
- /* update the current color map to best available colors */
-
- colorupd(twp)
- struct winds * twp;
- {
- RGBColor * srccolor = &twp->ibmcolormap.colors[0];
- RGBColor * matchcolor = &twp->colormap.colors[0];
- unsigned long colorindex;
- int count;
-
- if (!twp->color)
- return;
-
- for (count = 0; count++ < MAXCOLORS; srccolor++, matchcolor++) {
- colorindex = Color2Index(srccolor);
- Index2Color(colorindex, matchcolor);
- }
- }
-
-